package vendas.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;
import gminet.infra.toolkit.DateToolkit;
import gminet.infra.toolkit.NumberToolkit;
import gminet.infra.toolkit.StringToolkit;
import gminet.infra.toolkit.ValidatorToolkit;

import java.sql.Connection;
import java.util.Date;

import vendas.dao.UserDAO;
import vendas.dto.MasterUser;
import vendas.dto.User;
import vendas.dto.UserStatus;
import vendas.dto.UserType;


public class UserBusiness extends BusinessObject {

    public static User insert(User user) throws BusinessException, TransactionException {

        User newUser = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            //
            if (UserDAO.existEmail(user.getEmail(), conn)) {
                throw new BusinessException("E-mail já cadastrado para outro usuário.");
            }
            // USUARIO
            Date dataAtual = DateToolkit.getDate();
            int rangeId = createRangeId(user.getName());
            user.setId(UserDAO.getNextCodigo(conn, rangeId, rangeId + 1000));
            user.setStatus(UserStatus.PENDENT);
            user.setType(UserType.USER);
            user.setPassword(LoginBusiness.crypt(user.getPassword()));
            user.setCreationDate(dataAtual);
            UserDAO.insert(user, conn);
            // COMMIT
            transaction.commit();
            //
            newUser = user;
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return newUser;
    }

    private static int createRangeId(String userName) {

        String strCodigo = "1";
        String caracter1 = userName.substring(0, 1).toUpperCase();
        String caracter2 = userName.substring(1, 2).toUpperCase();
        int valor1 = Math.abs(caracter1.compareTo("A") + 1);
        if (StringToolkit.isDigit(caracter1)) {
            valor1 = 0;
        }
        int valor2 = Math.abs(caracter2.compareTo("A") / 3);
        if (StringToolkit.isDigit(caracter2)) {
            valor2 = 0;
        }
        strCodigo += NumberToolkit.getStringFromInt(Math.min(valor1, 99), 2);
        strCodigo += NumberToolkit.getStringFromInt(Math.min(valor2, 9), 1);
        strCodigo += "000";
        return Integer.parseInt(strCodigo);
    }

    public static void update(User user) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            User auxUser = UserDAO.findByPK(user.getId(), conn);
            user.setStatus(auxUser.getStatus());
            user.setType(auxUser.getType());
            UserDAO.update(user, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void updatePassword(User user) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            user.setPassword(LoginBusiness.crypt(user.getPassword()));
            updatePassword(user, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void updatePassword(User user, Connection conn) throws BusinessException, TransactionException {

        UserDAO.updatePassword(user, conn);
    }

    public static void delete(User user) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            UserDAO.delete(user, conn);
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void verifyEmail(String email) throws TransactionException, BusinessException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            if (!StringToolkit.isFill(email) || !ValidatorToolkit.validateEmail(email)) {
                throw new BusinessException("Email inválido.", "email");
            }
            if (email.equalsIgnoreCase(MasterUser.getInstance().getEmail())) {
                throw new BusinessException("Email já cadastrado.", "email");
            }
            if (UserDAO.existEmail(email, conn)) {
                throw new BusinessException("Email já cadastrado por outro cliente.", "email");
            }
        } finally {
            transaction.release();
        }
    }

}
